#include <iostream>
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;


/*
	opencv滑块交互操作：
		滑动条(Trackbar) 是opencv动态调节参数特别好用的- -种工具,虽然看起来着实有点丑

		滑动条创建函数
			int createTrackbar(const String& trackbarname, const String& winname, int* value, int count, TrackbarCallback onChange = 0, void* userdata = 0);
				trackbarname:滑动条名字
				winname:依附窗口名
				value:滑块位置
				count:滑块最大值（最小值是0）
				onChange:滑块回调函数
				userdata:用户回传给回调函数的数据

		滑动条回调函数:
				typedef void (*TrackbarCallback)(int pos, void* userdata);
				void On_TrackBar(int pos,void* userdata);
					pos:位置
					userdata:用户回传给回调函数的数据
*/

class TrackBar
{
private:
	Mat mat;
	int m_curBright;			//当前亮度
	int m_maxBright;			//最大亮度

public:
	TrackBar(const string& filename)
		:mat(imread(filename))
		, m_curBright(2)
		, m_maxBright(10)
	{

	}
	void Show(const string& wname = "trackBar")
	{
		imshow(wname, mat);
	}
	int* getCurData()
	{
		return &m_curBright;
	}
	int getMaxData()
	{
		return m_maxBright;
	}

	static void On_TrackBar(int pos, void* userdata);

};

void TrackBar::On_TrackBar(int pos, void* userdata)
{
	TrackBar* bar = (TrackBar*)userdata;
	//如果用户数据中的图像信息为空，那就退出好了:
	if (!bar->mat.data)
	{
		return;
	}


	Mat result = Mat::zeros(bar->mat.size(), bar->mat.type());
	float beta = 30;
	float alpha = 0.1f + (float)bar->m_curBright / 10.0;


	int dims = bar->mat.channels();				//获取通道数:
	for (int r = 0; r < bar->mat.rows; r++)
	{
		for (int c = 0; c < bar->mat.cols; c++)
		{
			if (1 == dims)												//单通道
			{
				float bgr = bar->mat.at<uchar>(r, c);

				result.at<uchar>(r, c) = saturate_cast<uchar>(bgr*alpha +beta);
			}
			else if (3 == dims)											//三通道
			{
				float B = bar->mat.at<Vec3b>(r, c)[0];
				float G = bar->mat.at<Vec3b>(r, c)[1];
				float R = bar->mat.at<Vec3b>(r, c)[2];

				result.at<Vec3b>(r, c)[0] = saturate_cast<uchar>(B * alpha + beta);
				result.at<Vec3b>(r, c)[1] = saturate_cast<uchar>(G * alpha + beta);
				result.at<Vec3b>(r, c)[2] = saturate_cast<uchar>(R * alpha + beta);
			}
			else
			{
				return;
			}
		}
	}


	imshow("trackBar", result);
}

int main()
{
	unique_ptr<TrackBar> bar(new TrackBar("mm.jpg"));
	namedWindow("trackar");

	createTrackbar("亮度调整老", "trackBar", bar->getCurData(), bar->getMaxData(), TrackBar::On_TrackBar, bar);
	waitKey();


	return 0;
}

